unit uDBGridLineColor;

interface

uses
  DB, SysUtils, Classes, Controls, Grids, DBGrids, DBCtrls, windows,
  Graphics, Forms, ZDataSet,
  ZAbstractRODataset;


type
  TDBLCStyle = (dblcAlternatedColor, dblcSelections) ;

  TDBGridLineColor = class(TDBGrid)
  private
    vLineColor1: TColor;
    vLineColor2: TColor;
    vFontColor1: TColor;
    vFontColor2: TColor;
    vULineColor: TColor;
    vUFontColor: TColor;
    vUltimaCor: Integer;
    vCamposCheck: TStrings;
    GridCheckBox: TDBCheckBox;
    vStyle: TDBLCStyle;

    function EhChecked(Coluna: Integer): Boolean;
    procedure SetCamposCheck(const Value: TStrings);
    procedure CellClick(Column: TColumn); override;
    procedure MouseMove (Shift: TShiftState; X, Y: Integer); override;
    procedure TitleClick(Column: TColumn); override;


    { Private declarations }
  protected
    { Protected declarations }
  public
    constructor Create(AOwner: TComponent); override;
    procedure ColExit; override;
    procedure KeyPress(var Key: Char); override;

    procedure GridCheckBoxClick(Sender: TObject);

    procedure DrawColumnCell(
        const  Rect: TRect; DataCol: Integer; Column: TColumn;
        State: TGridDrawState); override;
  published
    property LineColor1 : TColor read vLineColor1 write vLineColor1;
    property LineColor2 : TColor read vLineColor2 write vLineColor2;
    property FontColor1 : TColor read vFontColor1 write vFontColor1;
    property FontColor2 : TColor read vFontColor2 write vFontColor2;
    property CamposCheck: TStrings read vCamposCheck write SetCamposCheck;
    property Style: TDBLCStyle read vStyle write vStyle;
    { Published declarations }
  end;


procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('MRSoftware', [TDBGridLineColor]);
end;

{ TDBGridLineColor }

procedure TDBGridLineColor.CellClick(Column: TColumn);
var
    gravar, dentro, dentro2 : boolean;
    pt: TPoint;
    soma, i: integer;
begin
  inherited;
    if self.Style = dblcSelections then
    begin
        for i := 0 to CamposCheck.Count - 1 do
        begin
            if Column.Index = StrToInt(CamposCheck[i]) then
                dentro := true;
        end;

        if not dentro then exit;

        if not (Self.DataSource.DataSet.State in [dsInsert, dsEdit]) then
        begin
            Self.DataSource.DataSet.Edit;
            gravar := true;
        end else gravar := false;

        if GridCheckBox.Field.Value = GridCheckBox.ValueChecked then
            GridCheckBox.Field.Value := GridCheckBox.ValueUnchecked
        else
            GridCheckBox.Field.Value := GridCheckBox.ValueChecked;

        if gravar then self.DataSource.DataSet.Post;
    end;

end;

procedure TDBGridLineColor.ColExit;
begin
  inherited;
    if self.Style = dblcSelections then
        if Self.SelectedField.FieldName = GridCheckBox.DataField then
            GridCheckBox.Visible := False;
end;

constructor TDBGridLineColor.Create(AOwner: TComponent);
var
    i: integer;
begin
  inherited;
    DrawingStyle := gdsGradient;
    LineColor2 := $00E2E2E2;
    LineColor1 := clWhite;
    vCamposCheck := TStringList.Create;
    vCamposCheck.Text := '';
    Style := dblcAlternatedColor;

end;

procedure TDBGridLineColor.MouseMove(Shift: TShiftState; X, Y: Integer);
var
  pt: TGridcoord;
begin
  inherited;
  pt:= Self.MouseCoord(x, y);

  if pt.y=0 then
    Self.Cursor:=crHandPoint
  else
    Self.Cursor:=crDefault;
end;

procedure TDBGridLineColor.DrawColumnCell(const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
const IsChecked : array[Boolean] of Integer =
      (DFCS_BUTTONCHECK, DFCS_BUTTONCHECK or DFCS_CHECKED);
var
    DrawState: Integer;
    DrawRect: TRect;
    recordnumero: integer;
begin
    inherited;

    if self.Style = dblcAlternatedColor then
    begin
          //if Column.Index = 0 then
          begin
            recordnumero := Self.DataSource.DataSet.RecNo;

            if (recordnumero / 2)  = (Trunc(recordnumero /2)) then
            begin
                vUltimaCor := 2;
                vULineColor := vLineColor2;
                vUFontColor := vFontColor2;
            end else
            begin
                vUltimaCor := 1;
                vULineColor := vLineColor1;
                vUFontColor := vFontColor1;
            end;
          end;

          Canvas.Brush.Color := vULineColor;
          Canvas.Font.Color := vUFontColor;

          DefaultDrawColumnCell(rect,datacol,column,state);
    end else
    begin
          if vCamposCheck.Count <= 0 then Exit;

          if GridCheckBox = nil then
          begin
                GridCheckBox := TDBCheckBox.Create(Self.Parent);
                GridCheckBox.Parent := Self.Parent;
                GridCheckBox.DataSource := Self.DataSource;
                GridCheckBox.Caption := '';
                GridCheckBox.Visible := false;
                GridCheckBox.ValueChecked := 'S';
                GridCheckBox.ValueUnchecked := 'N';
                GridCheckBox.DataField := Self.Columns[StrToInt(vCamposCheck[0])].FieldName;
          end;

          if (gdFocused in State) then
          begin
                //if EhChecked(Column.Index) then
                if GridCheckBox <> nil then
                begin
                    if (Column.Field.FieldName = GridCheckBox.DataField) then
                    begin
                     GridCheckBox.Left := Rect.Left + Self.Left + 2;
                     GridCheckBox.Top := Rect.Top + Self.top + 2;
                     GridCheckBox.Width := Rect.Right - Rect.Left;
                     GridCheckBox.Height := Rect.Bottom - Rect.Top;
                     GridCheckBox.Visible := True;
                     GridCheckBoxClick(GridCheckBox);
                    end
                end;
          end else
          begin
                //if EhChecked(Column.Index) then
                if GridCheckBox <> nil then
                begin
                    if (Column.Field.FieldName = GridCheckBox.DataField) then
                    begin
                      DrawRect:=Rect;
                      InflateRect(DrawRect,-1,-1);

                      DrawState := ISChecked[Column.Field.AsBoolean];

                      Self.Canvas.FillRect(Rect);
                      if Column.Field.Value = GridCheckBox.ValueChecked then
                          DrawFrameControl(Self.Canvas.Handle, DrawRect,
                                           DFC_BUTTON, DFCS_CHECKED)
                      else
                          DrawFrameControl(Self.Canvas.Handle, DrawRect,
                                           DFC_BUTTON, DFCS_BUTTONCHECK);
                    end;
                end;
          end;
    end;


end;

function TDBGridLineColor.EhChecked(Coluna: Integer): Boolean;
var
    i:  integer;
    retorno: boolean;
begin
    retorno := false;
    for i := 0 to vCamposCheck.Count - 1 do
    begin
        if StrToInt(vCamposCheck[i]) = Coluna then
        begin
            retorno := true;
            if GridCheckBox = nil then
            begin
                GridCheckBox := TDBCheckBox.Create(Self.Parent);
                GridCheckBox.Parent := Self.Parent;
                GridCheckBox.DataSource := Self.DataSource;
                GridCheckBox.Caption := '';
                GridCheckBox.Visible := false;
                GridCheckBox.ValueChecked := 'S';
                GridCheckBox.ValueUnchecked := 'N';
                GridCheckBox.DataField := Self.Columns[i].FieldName;
                GridCheckBox.OnClick := GridCheckBoxClick;
            end;
        end;

    end;

    result := retorno;
end;




procedure TDBGridLineColor.GridCheckBoxClick(Sender: TObject);
var
    gravar, dentro, dentro2 : boolean;
    pt: TPoint;
    soma: integer;
begin
        {GetCursorPos(pt);
        dentro := false;
        dentro2 := false;
        if (pt.X >= (GridCheckBox.left + GridCheckBox.Parent.left)) and (pt.X <= (GridCheckBox.left + GridCheckBox.Parent.left + 20)) then
            dentro := true;

        if (GridCheckBox.Parent is TForm) then
            soma := (GridCheckBox.Parent as TForm).Height - (GridCheckBox.Parent as TForm).ClientHeight
        else
            soma := 0;


        if (pt.Y >= (GridCheckBox.top + GridCheckBox.Parent.top + soma)) and (pt.y <= (GridCheckBox.top + GridCheckBox.Parent.top + 20 + soma)) then
            dentro2 := true;

        if not (dentro and dentro2) then exit;
        }
{    if self.Style = dblcSelections then
    begin
        if not (Self.DataSource.DataSet.State in [dsInsert, dsEdit]) then
        begin
            Self.DataSource.DataSet.Edit;
            gravar := true;
        end else gravar := false;

        if GridCheckBox.Field.Value = GridCheckBox.ValueChecked then
            GridCheckBox.Field.Value := GridCheckBox.ValueUnchecked
        else
            GridCheckBox.Field.Value := GridCheckBox.ValueChecked;

        if gravar then self.DataSource.DataSet.Post;
    end;
}

end;


procedure TDBGridLineColor.KeyPress(var Key: Char);
begin
  inherited;

  if self.Style = dblcSelections then
  begin
      if (key = Chr(9)) then Exit;

      if (Self.SelectedField.FieldName = GridCheckBox.DataField) and
        GridCheckBox.Visible
      then
      begin
        GridCheckBox.SetFocus;
        SendMessage(GridCheckBox.Handle, 258, word(Key), 0);
      end;
  end;
end;

procedure TDBGridLineColor.SetCamposCheck(const Value: TStrings);
begin
    vCamposCheck.Assign(Value);
end;

procedure TDBGridLineColor.TitleClick(Column: TColumn);
{$J+}
 const PreviousColumnIndex : integer = -1;
{$J-}
begin
  inherited;

    try
      Self.Columns[PreviousColumnIndex].title.Font.color := clBlack;
    except
    end;

    Column.title.Font.Color := clRed;
    PreviousColumnIndex := Column.Index;

    //para ordenar varios campos utilizar
    //(Self.DataSource.DataSet as TZReadOnlyQuery).IndexFieldNames
    if (Self.DataSource.DataSet is TZReadOnlyQuery) then
    begin
        if (Self.DataSource.DataSet as TZReadOnlyQuery).SortedFields <> Column.Field.FieldName then
            (Self.DataSource.DataSet as TZReadOnlyQuery).SortedFields := Column.Field.FieldName
        else begin
            if (Self.DataSource.DataSet as TZReadOnlyQuery).SortType = stAscending then
                (Self.DataSource.DataSet as TZReadOnlyQuery).SortType := stDescending
            else
                (Self.DataSource.DataSet as TZReadOnlyQuery).SortType := stAscending;
        end;

    end else if (Self.DataSource.DataSet is TZQuery) then
    begin
        if (Self.DataSource.DataSet as TZQuery).SortedFields <> Column.Field.FieldName then
            (Self.DataSource.DataSet as TZQuery).SortedFields := Column.Field.FieldName
        else begin
            if (Self.DataSource.DataSet as TZQuery).SortType = stAscending then
                (Self.DataSource.DataSet as TZQuery).SortType := stDescending
            else
                (Self.DataSource.DataSet as TZQuery).SortType := stAscending;
        end;

    end else if (Self.DataSource.DataSet is TZTable) then
    begin
        if (Self.DataSource.DataSet as TZTable).SortedFields <> Column.Field.FieldName then
            (Self.DataSource.DataSet as TZTable).SortedFields := Column.Field.FieldName
        else begin
            if (Self.DataSource.DataSet as TZTable).SortType = stAscending then
                (Self.DataSource.DataSet as TZTable).SortType := stDescending
            else
                (Self.DataSource.DataSet as TZTable).SortType := stAscending;
        end;


    end;
    (Self.DataSource.DataSet as TDataSet).First;




    {if (Pos(Column.Field.FieldName, Sort) = 1)
    and (Pos(' DESC', Sort)= 0) then
      Sort := Column.Field.FieldName + ' DESC'
    else
      Sort := Column.Field.FieldName + ' ASC';
  end;                                        }

end;

end.
